#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "./lcd/bsp_ili9341_lcd.h"
#include "usart.h"
#include "key.h"
#include "queue.h"
#include "semphr.h"
#include "stdio.h"

static TaskHandle_t AppTaskCreate_Handle = NULL;
static TaskHandle_t LowPriority_Task_Handle = NULL;
static TaskHandle_t MidPriority_Task_Handle = NULL;
static TaskHandle_t HighPriority_Task_Handle = NULL;


SemaphoreHandle_t MutexSem_Handle = NULL;


static void AppTaskCreate(void);

static void LowPriority_Task(void* pvParameters);
static void MidPriority_Task(void* pvParameters);
static void HighPriority_Task(void* pvParameters);

//用于使用互斥量的话 低优先级的任务就不会被中优先级的任务一直打断
//可以理解为互斥锁是代码临界区保护 信号量是通知
int main(void)
{ 
	BaseType_t xReturn = pdPASS;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	KEY_Init();
	LED_Init();		        //初始化LED端口
	ILI9341_Init();//液晶初始化    
	LCD_SetColors(BLACK,WHITE);//设置白底黑字
	LCD_SetFont(&Font8x16);//设置字体大小
	ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);//清屏
  ILI9341_GramScan ( 6 );//设置显示模式
	USART_Config(115200);
  LED_Color(LED_OFF);
	
	xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,  
                        (const char*    )"AppTaskCreate",
                        (uint16_t       )512, 
                        (void*          )NULL,
                        (UBaseType_t    )1, 
                        (TaskHandle_t*  )&AppTaskCreate_Handle);
	if(pdPASS == xReturn){
		vTaskStartScheduler();          //开启任务调度
	}
  else{
		printf("Error Start RTOS\n");
	}
	
}


static void AppTaskCreate(void)
{
  BaseType_t xReturn = pdPASS;
  
  taskENTER_CRITICAL();           
  
  MutexSem_Handle = xSemaphoreCreateMutex();	 
  if(NULL != MutexSem_Handle)
    printf("Success Create MutexSem_Handle!\r\n");

  xReturn = xSemaphoreGive( MutexSem_Handle );
  xReturn = xTaskCreate((TaskFunction_t )LowPriority_Task,
                        (const char*    )"LowPriority_Task",
                        (uint16_t       )512,  
                        (void*          )NULL,	
                        (UBaseType_t    )2,	   
                        (TaskHandle_t*  )&LowPriority_Task_Handle);
  if(pdPASS == xReturn)
    printf("Success Create LowPriority_Task!\n");
  
  xReturn = xTaskCreate((TaskFunction_t )MidPriority_Task, 
                        (const char*    )"MidPriority_Task",
                        (uint16_t       )512,
                        (void*          )NULL,
                        (UBaseType_t    )3, 
                        (TaskHandle_t*  )&MidPriority_Task_Handle);
  if(pdPASS == xReturn)
    printf("Success Create MidPriority_Task!\n");
  
  xReturn = xTaskCreate((TaskFunction_t )HighPriority_Task,  
                        (const char*    )"HighPriority_Task",
                        (uint16_t       )512,  
                        (void*          )NULL,
                        (UBaseType_t    )4, 
                        (TaskHandle_t*  )&HighPriority_Task_Handle);
  if(pdPASS == xReturn)
    printf("Success Create HighPriority_Task!\n");
  
  vTaskDelete(AppTaskCreate_Handle); 
	
  taskEXIT_CRITICAL();           
}

static void LowPriority_Task(void* parameter)
{	
  static uint32_t i;
  BaseType_t xReturn = pdPASS;
  while (1)
  {
    printf("LowPriority_Task Get Sem\n");

		xReturn = xSemaphoreTake(MutexSem_Handle,portMAX_DELAY); 
    if( xReturn == pdTRUE )
      printf("LowPriority_Task Running\n");
    
    for(i=0;i<2000000;i++)
		{
			taskYIELD();
		}
    
    printf("LowPriority_Task Free Sem\r\n");
    xReturn = xSemaphoreGive( MutexSem_Handle );
    
    vTaskDelay(500);
  }
}

static void MidPriority_Task(void* parameter)
{	 
  while (1)
  {
   printf("MidPriority_Task Running\n");
   vTaskDelay(500);
  }
}

static void HighPriority_Task(void* parameter)
{	
  BaseType_t xReturn = pdTRUE;
  while (1)
  {
    printf("HighPriority_Task Get Sem\n");
		xReturn = xSemaphoreTake(MutexSem_Handle,portMAX_DELAY); 
    if(pdTRUE == xReturn)
      printf("HighPriority_Task Is Running\n");

		printf("HighPriority_Task Free Sem\r\n");
    xReturn = xSemaphoreGive( MutexSem_Handle );
    vTaskDelay(500);
  }
}